<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\common\Platform;
use app\common\Sms;
use app\common\Tencent;
use app\common\UserService;
use app\model\Advise;
use app\model\AdviseClass;
use app\model\Config;
use app\model\LoginScan;
use app\model\User;
use app\model\UserCollect;
use app\model\UserScoreLog;
use app\tool\Random;
use DateTime;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Tencent\TLSSigAPIv2;
use thans\jwt\facade\JWTAuth;
use think\db\Query;
use think\facade\Db;
use think\facade\Env;

class UserController extends BaseController
{
    function login()
    {
        $logintype = $this->request->post('logintype');# 登陆方式:mobile=手机号,wechat=微信
        $mobile = $this->request->post('mobile', '');
        $captcha = $this->request->post('captcha');
        $wechatcode = $this->request->post('wechatcode');
        $web_openid = '';
        $mobile_openid = '';
        $unionid = '';
        switch ($logintype) {
            case 'mobile':
                if (empty($mobile) || empty($captcha)) {
                    $this->writeJson(0, '手机号或验证码不能为空');
                }
                $captchaResult = Sms::check($mobile, $captcha, 'login');
                if (!$captchaResult) {
                    $this->writeJson(0, '验证码错误');
                }
                $user = User::where(['mobile' => $mobile])->find();
                break;
            case 'wechat':
                if (empty($wechatcode)) {
                    $this->writeJson(0, '微信code不能为空');
                }
                try {
                    if ($this->request->header('Client') == 'app') {
                        $wechat = Platform::getWechatMobileAccessToken($wechatcode);
                        $mobile_openid = $wechat->openid;
                    } else {
                        $wechat = Platform::getWechatWebAccessToken($wechatcode);
                        $web_openid = $wechat->openid;
                    }
                }catch (\Throwable $e){
                    $this->writeJson(0,$e->getMessage());
                }
                $user = User::where(['unionid' => $wechat->unionid])->find();
                $unionid = $wechat->unionid;
                break;
            default:
                $this->writeJson(0, '登陆方式错误');
        }
        $ip = request()->ip();
        $time = time();
        if (!$user) {
            do {
                $nickname = '用户' . rand(1000000, 9999999);
            } while (User::where(['nickname' => $nickname])->find());
            do {
                $invitecode = Random::alnum();
            } while (User::where(['invitecode' => $invitecode])->find());
            // 启动事务
            Db::startTrans();
            try {
                $data = [
                    'mobile' => $mobile,
                    'level' => 1,
                    'score' => 0,
                    'avatar' => '/assets/img/avatar.png',
                    'web_openid' => $web_openid,
                    'mobile_openid' => $mobile_openid,
                    'unionid' => $unionid,
                    'invitecode' => $invitecode,
                    'nickname' => $nickname,
                    'jointime' => $time,
                    'joinip' => $ip,
                    'logintime' => $time,
                    'loginip' => $ip,
                    'prevtime' => $time,
                    'status' => 'normal',
                ];
                $user = User::create($data);
                $TencentIm = Tencent::getInstance();
                $ret = json_decode($TencentIm->account_import('user_' . $user->id, $user->nickname, $user->avatar));
                if ($ret->ErrorCode != 0) {
                    throw new Exception('添加IM失败');
                }
                // 提交事务
                Db::commit();
            } catch (\Throwable $e) {
                // 回滚事务
                Db::rollback();
                $this->writeJson(0, $e->getMessage());
            }
            $register_score = Config::getFieldByName('register_score', 'value');
            try {
                UserService::changeUserScore($register_score, $user->id, '新人注册');
            } catch (Exception $e) {
                $this->writeJson(0, $e->getMessage());
            }
            $token = JWTAuth::builder(['user_id' => $user->id]);
            if (empty($user->mobile)) {
                $this->writeJson(101, '请绑定手机号', ['Authorization' => 'Bearer ' . $token]);
            }
            if (empty($user->pid)) {
                $this->writeJson(102, '请绑定邀请码', '', 'json', ['Authorization' => 'Bearer ' . $token]);
            }
        } else {
            if ($user->status == 'hidden') {
                $this->writeJson(0, '账号被封禁');
            }
            $user->prevtime = $user->logintime;
            $user->logintime = $time;
            $user->loginip = $ip;
            if (!empty($web_openid) && empty($user->web_openid)) {
                $user->web_openid = $web_openid;
            }
            if (!empty($mobile_openid) && empty($user->mobile_openid)) {
                $user->mobile_openid = $mobile_openid;
            }
            $user->save();
            $token = JWTAuth::builder(['user_id' => $user->id]);
            if (empty($user->mobile)) {
                $this->writeJson(101, '请绑定手机号', ['Authorization' => 'Bearer ' . $token]);
            }
        }

        $this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
    }

    #绑定手机号
    function bindMobile()
    {
        $mobile = $this->request->post('mobile');
        $captcha = $this->request->post('captcha');
        if (empty($mobile) || empty($captcha)) {
            $this->writeJson(0, '手机号或验证码不能为空');
        }
        try {
            Sms::check($mobile, $captcha, 'changemobile');
        }catch (\Throwable $e) {
            $this->writeJson(0, $e->getMessage());
        }

        $user = User::findOrFail($this->user_id);
        $user->mobile = $mobile;
        $user->save();
        $token = JWTAuth::builder(['user_id' => $user->id]);
        if (empty($user->pid)) {
            $this->writeJson(101, '绑定邀请码', '', 'json', ['Authorization' => 'Bearer ' . $token]);
        }
        $this->writeJson(1, '绑定成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
    }



    #获取登录二维码
    function getLoginScanQr()
    {
        $uuid = Random::uuid();
        $writer = new PngWriter();
        $qrCode = QrCode::create(json_encode(['action'=>'getLoginScanQr','uuid'=>$uuid]))//跳转的url地址
        ->setSize(100)      //大小
        ->setMargin(0)             //边距
        ->setForegroundColor(new Color(0, 0, 0))        //前景色
        ->setBackgroundColor(new Color(255, 255, 255));       //背景色
        $result = $writer->write($qrCode)->getDataUri();
        LoginScan::create([
            'uuid'=>$uuid,
        ]);
        $this->writeJson(['qrcode'=>$result,'uuid'=>$uuid]);
    }

    #轮询请求扫码状态
    function getLoginScanStatus()
    {
        $uuid = $this->request->get('uuid');
        $row = LoginScan::where(['uuid' => $uuid])->find();
        if (!$row){
            $this->writeJson(101,'二维码不存在,停止请求');
        }
        #两分钟过期
        if ($row->createtime + 120 <= time()){
            $this->writeJson(101,'二维码已过期,停止请求');
        }

        if (empty($row->token)){
            $this->writeJson(102,'未扫码,继续请求');
        }

        $this->writeJson(1, '登陆成功', '', 'json', ['Authorization' => 'Bearer ' . $row->token]);
    }

    #扫描二维码
    function doScanQrCode()
    {
        $content = $this->request->post('content');
        if (empty($content)) {
            $this->writeJson(0, '扫码内容为空');
        }
        $content = json_decode($content);
        if (!isset($content->action)) {
            $this->writeJson(0, '操作错误');
        }

        switch ($content->action) {
            case 'getLoginScanQr':
                $uuid = $content->uuid;
                $row = LoginScan::where(['uuid' => $uuid])->find();
                if (!$row){
                    $this->writeJson(0,'二维码不存在');
                }
                #两分钟过期
                if ($row->createtime + 120 <= time()){
                    $this->writeJson(0,'二维码已过期');
                }

                if ($row->token){
                    $this->writeJson(0,'二维码已被使用');
                }

                $token = JWTAuth::token();
                $row->token = $token;
                $row->save();
                break;
            default:
                $this->writeJson(0, '参数错误');
        }
        $this->writeJson();
    }

    #积分记录
    function userScore()
    {
        $status = $this->request->get('status/d'); // 0全部 1支出 2收入
        $rows = UserScoreLog::where(['user_id' => $this->user_id])->when(!empty($status), function (Query $query) use ($status) {
            if ($status == 1) {
                $query->where('score', '<=', 0);
            } else {
                $query->where('score', '>=', 0);
            }
        })->filter(function ($data) {
            if ($data->score > 0) {
                $data->score = '+' . $data->score;
            }
        })->order(['id' => 'desc'])->paginate()->items();
        $this->writeJson($rows);
    }

    #二维码
    function getQrCode()
    {
        $user = User::findOrFail($this->user_id);
        $writer = new PngWriter();
        $qrCode = QrCode::create(json_encode(['action' => 'user_info', 'user_id' => $user->id]))
            ->setSize(100)      //大小
            ->setMargin(0)             //边距
            ->setForegroundColor(new Color(0, 0, 0))        //前景色
            ->setBackgroundColor(new Color(255, 255, 255));       //背景色
        $result = $writer->write($qrCode)->getDataUri();
        $this->writeJson($result);
    }

    function getInviteImage()
    {
        $row = Config::getFieldByName('invite_image', 'value');
        if (empty($row)) {
            $this->writeJson(0, '邀请图片未设置');
        }
        $user = User::findOrFail($this->user_id);
        $writer = new PngWriter();
        $qrCode = QrCode::create(Env::get('H5_URL') . '?invitecode=' . $user->invitecode)
            ->setSize(100)      //大小
            ->setMargin(0)             //边距
            ->setForegroundColor(new Color(0, 0, 0))        //前景色
            ->setBackgroundColor(new Color(255, 255, 255));       //背景色
        $result = $writer->write($qrCode)->getDataUri();
        $this->writeJson(['qr_data' => $result, 'invitecode' => $user->invitecode, 'invite_image' => $row]);
    }

    function scan()
    {
        $to_user_id = $this->request->post('to_user_id/d');
        $score = $this->request->post('score/d');
        $user = User::findOrFail($this->user_id);
        if ($user->scan != 1) {
            $this->writeJson(0, '无权限访问');
        }
        try {
            UserService::changeUserScore(-$score, $to_user_id, '扫码核销');
        } catch (Exception $e) {
            $this->writeJson(102, $e->getMessage());
        }
        $this->writeJson(101, '扣除成功');
    }

    function getUserInfo()
    {
        $row = User::findOrFail($this->user_id);
        $this->writeJson($row);
    }

    function collect()
    {
        $status = $this->request->get('status/d'); #状态:1=正在进行,2=即将开始,3=已结束
        $room_ids = UserCollect::where(['user_id' => $this->user_id])->column('room_id');
        $rows = Room::whereIn('id', $room_ids)
            ->when(!empty($status), function (Query $query) use ($status) {
                $query->where('status', $status);
            })
            ->paginate()
            ->items();
        $this->writeJson($rows);
    }

    /**
     * 编辑个人信息
     * @return void
     */
    function userEdit()
    {
        $avatar = $this->request->post('avatar');
        $nickname = $this->request->post('nickname');
        $birthday = $this->request->post('birthday');
        $gender = $this->request->post('gender/d');//性别:1=男,2=女
        $user = User::findOrFail($this->user_id);
        $TencentIm = Tencent::getInstance();
        $info = [];
        if (!empty($avatar)) {
            $user->avatar = $avatar;
            $info[] = ['Tag' => 'Tag_Profile_IM_Image', 'Value' => $avatar];
        }
        if (!empty($nickname)) {
            $user->nickname = $nickname;
            $info[] = ['Tag' => 'Tag_Profile_IM_Nick', 'Value' => $nickname];

        }
        if (!empty($birthday)) {
            $user->birthday = $birthday;
            $date = new DateTime($birthday);
            $info[] = ['Tag' => 'Tag_Profile_IM_BirthDay', 'Value' => (int)$date->format('Ymd')];
        }
        if (!empty($gender)) {
            $user->gender = $gender;
            if ($gender == 1) {
                $info[] = ['Tag' => 'Tag_Profile_IM_Gender', 'Value' => 'Gender_Type_Male'];
            } else {
                $info[] = ['Tag' => 'Tag_Profile_IM_Gender', 'Value' => 'Gender_Type_Female'];
            }
        }
        Db::startTrans();
        try {
            $user->save();
            $ret = json_decode($TencentIm->portrait_set($user->id, $info));
            if ($ret->ErrorCode != 0) {
                throw new Exception('更新IM失败');
            }
            // 提交事务
            Db::commit();
        } catch (\Throwable $e) {
            // 回滚事务
            Db::rollback();
            $this->writeJson(0, $e->getMessage());
        }
        $this->writeJson();
    }


    /**
     * 获取腾讯ImSign
     */
    function getImSign()
    {
        $identifier = $this->user_id;
        $im = config('platform.im');
        $api = new TLSSigAPIv2($im['appid'], $im['secret']);
        $sig = $api->genUserSig($identifier);
        $this->writeJson($sig);
    }

    function getChild()
    {
        $user = User::findOrFail($this->user_id);
        $child = $user->child();
        $this->writeJson(['count' => $child->count(), 'list' => $child->paginate()->items()]);
    }

    function adviseClass()
    {
        $rows = AdviseClass::order(['weigh' => 'desc'])->select();
        $this->writeJson($rows);
    }

    /**
     * 提建议
     * @return void
     */
    function adviseAdd()
    {
        $class_name = $this->request->post('class_name');
        $content = $this->request->post('content');
        $images = $this->request->post('images');
        $name = $this->request->post('name');
        $mobile = $this->request->post('mobile');
        if (empty($class_name)) {
            $this->writeJson(0, '分类填写错误');
        }
        if (empty($content)) {
            $this->writeJson(0, '内容必须填写');
        }
        if (empty($name)) {
            $this->writeJson(0, '姓名必须填写');
        }
        if (empty($mobile)) {
            $this->writeJson(0, '手机号码必须填写');
        }
        $data = [
            'content' => $content,
            'class_name' => $class_name,
            'images' => $images,
            'name' => $name,
            'mobile' => $mobile,
            'user_id' => $this->user_id,
        ];
        Advise::create($data);
        $this->writeJson();
    }

    function logoff()
    {
        $user = User::findOrFail($this->user_id);
        $user->delete();
        $this->writeJson();
    }


}
